home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
kcl
/
akcl
/
akcl1615.lha
/
c
/
rel_aix.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-07
|
3KB
|
111 lines
/* Copyright William Schelter. All rights reserved. This file does
the low level relocation which tends to be very system dependent.
It is included by the file sfasl.c
*/
#define EXTERNAL_P(rel) \
relocation_info.r_type & )
#define HI12 0xfff00000
#define LO20 ~HI12
foo(){};
relocate()
{
char *where;
{unsigned int new_value;
char tem [10];
#ifdef DEBUG
printf("\nEnter relocate:*srelocation_info {r_symndx= %d, r_vaddr = %d,:",
relocation_info.r_symndx,
relocation_info.r_vaddr
);fflush(stdout);
#endif
where = the_start + relocation_info.r_vaddr;
if(relocation_info.r_symndx < S_BSS){
#ifdef DEBUG
printf("(relocation_info.r_symndx = %d < S_BSS)",relocation_info.r_symndx
);fflush(stdout);
print_name(&symbol_table[relocation_info.r_symndx]);
#endif
switch(relocation_info.r_type){
case R_KCALL:
/* instructions like balix take a 20 bit argument
which wants to be the displacement in half words to
from the address of the instruction to the actual
address. */
{int displ;
unsigned int new;
displ= symbol_table[relocation_info.r_symndx].n_value -
(int)where;
new= *(unsigned int *)where;
/* *(unsigned int *)where
= (new & HI12) | ((displ >> 1) & LO20); */
/* need to store the halves separately, because word pointers
must be aligned */
((unsigned short *)where)[0]=0x8b00;
((unsigned short *)where)[1]=0x0c00;
return ;}
case R_PCRBYTE: /* byte (pc relative) */
case R_PCRWORD: /* word (pc relative) */
case R_PCRLONG: /* word (pc relative) */
new_value= - (int)start_address
+ symbol_table[relocation_info.r_symndx].n_value;
break;
default:
{ new_value=
symbol_table[relocation_info.r_symndx].n_value;}}}
else
{ switch(relocation_info.r_symndx){
case S_DATA: case S_BSS: case S_TEXT:
new_value= (int)start_address;
break;
default:
dprintf(relocation_info.r_type = %d, relocation_info.r_type);
#ifdef DEBUG
printf("\nrelocation_info {r_symndx= %d, r_vaddr = %d, Ignored:",
relocation_info.r_symndx,
relocation_info.r_vaddr
);fflush(stdout);
#endif
goto DONT;}
};
dprintf((type %d),relocation_info.r_type);
switch(relocation_info.r_type){
case R_RELBYTE:
case R_PCRBYTE:
*( char *)where = new_value + *( char *) where;
break;
case R_RELWORD:
case R_PCRWORD:
*( short *)where = new_value + *( short *) where;
break;
case R_RELLONG:
case R_PCRLONG:
/* I guess it must be long if in these areas
I don't see how the size can vary.
*/
if (((int)where %4) !=0) FEerror("long alignment not long aligned",0,0);
*( long *)where = new_value + *( long *) where;
break;
default:
printf("(bad type %d)",relocation_info.r_type);
}
DONT:;
}
}
typedef int (*FUNC)();
/* #define describe_sym(n) do{if (debug){printf("Sym No %d:",n); print_name(symbol_table+ (n));}}while(0)
*/
/* #include "spadutils.c" */